﻿// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Copyright (c) Microsoft Corporation. All rights reserved.

namespace Microsoft.Samples.Commerce.Catalog.CommerceEntities
{
    using Microsoft.Commerce.Contracts;
    using Microsoft.Samples.Commerce.Order.CommerceEntities;

    /// <summary>
    /// Represents catalog items that can be represented in the catalog hierarchy
    /// </summary>
    public class HierarchicalCatalogEntity : CatalogEntity
    {
        /// <summary>
        /// defines the model name for this commerce entity
        /// </summary>
        public new const string ModelNameDefinition = "HierarchicalCatalogEntity";

        /// <summary>
        /// Initializes a new instance of the <see cref="HierarchicalCatalogEntity"/> class.
        /// </summary>
        public HierarchicalCatalogEntity() : base()
        {
            this.CommerceEntity = new CommerceEntity(HierarchicalCatalogEntity.ModelNameDefinition);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="HierarchicalCatalogEntity"/> class.
        /// </summary>
        /// <param name="commerceEntity">The commerce entity.</param>
        public HierarchicalCatalogEntity(CommerceEntity commerceEntity)
            : base(commerceEntity)
        {
        }

        /// <summary>
        /// Gets or sets a collection containing the ancestor categories for the current catalog item.
        /// </summary>
        /// <value>a list of Relationships where the target is of type Category.</value>
        /// <remarks>
        /// Ancestor categories of a catalog item include all its parent categories, recursively.
        /// </remarks>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList AncestorCategories
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.AncestorCategories) as CommerceRelationshipList;
            }
         
            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.AncestorCategories, value);
            }
        }

        /// <summary>
        /// Gets or sets a collection containing the canonical categories for the current catalog item.
        /// </summary>
        /// <value>a list of Relationships where the target is of type Category.</value>
        /// <remarks>
        /// The canonical path of any category is formed by looking up the Primary Parent of this catalog
        /// item, the primary parent of that category, and so on until the root of the hierarchy is reached.
        /// </remarks>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList CanonicalCategories
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.CanonicalCategories) as CommerceRelationshipList;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.CanonicalCategories, value);
            }
        }

        /// <summary>
        /// Gets or sets the cross sells.
        /// </summary>
        /// <value>a list of Relationships where the target is of type HierarchicalCatalogEntity.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList CrossSells
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.CrossSells) as CommerceRelationshipList;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.CrossSells, value);
            }
        }

        /// <summary>
        /// Gets or sets the up sells.
        /// </summary>
        /// <value>a list of Relationships where the target is of type HierarchicalCatalogEntity.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList UpSells
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.UpSells) as CommerceRelationshipList;
            }
         
            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.UpSells, value);
            }
        }

        /// <summary>
        /// Gets or sets the discounts.
        /// </summary>
        /// <value>a list of Relationships where the target is of type DiscountDefinition.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList DiscountDefinitions
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.DiscountDefinitions) as CommerceRelationshipList;
            }
         
            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.DiscountDefinitions, value);
            }
        }

        /// <summary>
        /// Gets or sets a collection containing the parent categories for the current catalog item.
        /// </summary>
        /// <value>a list of Relationships where the target is of type Category.</value>
        /// <remarks>
        /// This collection contains the categories that are immediate parents of this catalog item.
        /// </remarks>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList ParentCategories
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.ParentCategories) as CommerceRelationshipList;
            }
         
            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.ParentCategories, value);
            }
        }

        /// <summary>
        /// Gets or sets the related categories.       
        /// The CommerceRelationship is of type CatalogRelationship
        /// </summary>
        /// <value>a list of Relationships where the target is of type Category.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList RelatedCategories
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.RelatedCategories) as CommerceRelationshipList;
            }
         
            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.RelatedCategories, value);
            }
        }

        /// <summary>
        /// Gets or sets the related products.        
        /// The CommerceRelationship is of type CatalogRelationship
        /// </summary>
        /// <value>a list of Relationships where the target is of type Product.</value>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "Collection setting is required")]
        public CommerceRelationshipList RelatedProducts
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.RelatedProducts) as CommerceRelationshipList;
            }
         
            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.RelatedProducts, value);
            }
        }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>The description.</value>
        public string Description
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(PropertyName.Description) as string;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(PropertyName.Description, value);
            }
        }

        /// <summary>
        /// Gets or sets the primary parent category for the current catalog item.
        /// </summary>
        /// <value>The name of the primary parent category.</value>
        public CommerceRelationship PrimaryParentCategory
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.PrimaryParentCategory) as CommerceRelationship;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.PrimaryParentCategory, value);
            }
        }

        /// <summary>
        /// Gets or sets the base catalog relationship for the current catalog item.
        /// </summary>
        /// <value>The catalog.</value>
        /// <remarks>The relationship is of type Catalog.</remarks>
        public CommerceRelationship BaseCatalog
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.BaseCatalog) as CommerceRelationship;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.BaseCatalog, value);
            }
        }

        /// <summary>
        /// Gets or sets the catalog relationship for the current catalog item.
        /// </summary>
        /// <value>The catalog.</value>
        /// <remarks>The relationship is of type Catalog.</remarks>
        public CommerceRelationship Catalog
        {
            get
            {
                return this.CommerceEntity.GetPropertyValue(RelationshipName.Catalog) as CommerceRelationship;
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(RelationshipName.Catalog, value);
            }
        }

        /// <summary>
        /// Gets or sets the flag indicating if the catalog entity is part of a virtual catalog.
        /// </summary>
        /// <value>A the flag indicating if the catalog entity is part of a virtual catalog.</value>
        public bool? IsVirtualCatalog
        {
            get
            {
                return (bool?)this.CommerceEntity.GetPropertyValue(PropertyName.IsVirtualCatalog);
            }

            set
            {
                this.CommerceEntity.SetPropertyValue(PropertyName.IsVirtualCatalog, value ?? value);
            }
        }

        /// <summary>
        /// Names of the properties exposed by this commerce entity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public new class PropertyName : CatalogEntity.PropertyName
        {
            /// <summary>
            /// The name of the Description property.
            /// </summary>
            public const string Description = "Description";
            
            /// <summary>
            /// The name of the IsVirtualCatalog property.
            /// </summary>
            public const string IsVirtualCatalog = "IsVirtualCatalog";
        }
        
        /// <summary>
        /// Class defining Properties of Items that may be related to a CatalogEntity.
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", Justification = "Required because of API specification (i.e. DataContract design)")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible", Justification = "Needed for external access"), System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1053:StaticHolderTypesShouldNotHaveConstructors", Justification = "Cannot make it private as it cannot be derived from")]
        public class RelationshipName
        {
            /// <summary>
            /// The name of the AncestorCategories relationship.
            /// </summary>
            public const string AncestorCategories = "AncestorCategories";
            
            /// <summary>
            /// The name of the CanonicalCategories relationship.
            /// </summary>
            public const string CanonicalCategories = "CanonicalCategories";
            
            /// <summary>
            /// The name of the CrossSells relationship.
            /// </summary>
            public const string CrossSells = "CrossSells";
            
            /// <summary>
            /// The name of the UpSells relationship.
            /// </summary>
            public const string UpSells = "UpSells";
            
            /// <summary>
            /// The name of the DiscountDefinitions relationship.
            /// </summary>
            public const string DiscountDefinitions = "DiscountDefinitions";
            
            /// <summary>
            /// The name of the ParentCategories relationship.
            /// </summary>
            public const string ParentCategories = "ParentCategories";
            
            /// <summary>
            /// The name of the RelatedCategories relationship.
            /// </summary>
            public const string RelatedCategories = "RelatedCategories";
            
            /// <summary>
            /// The name of the RelatedProducts relationship.
            /// </summary>
            public const string RelatedProducts = "RelatedProducts";
            
            /// <summary>
            /// The name of the BaseCatalog relationship.
            /// </summary>
            public const string BaseCatalog = "BaseCatalog";
            
            /// <summary>
            /// The name of the Catalog relationship.
            /// </summary>
            public const string Catalog = "Catalog";
            
            /// <summary>
            /// The name of the PrimaryParentCategory relationship.
            /// </summary>
            public const string PrimaryParentCategory = "PrimaryParentCategory";
        }
    }
}